本文主要是记录 Git 在实际开发中的常见用法和技巧
环境配置(Mac)
1. 检查环境变量
在终端输入 git,如果出现下面的提示,则需要先初始化 xcode
Agreeing to the Xcode/iOS license requires admin privileges, please run “sudo xcodebuild -license” and then retry this command.
打开 Xcode 软件进行初始化即可,之后再次输入’git’,出现下面的提示则说明,环境变量配置成功
usage: git [--version] [--help] [-C <path>] [-c <name>=<value>]
[--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]
[-p | --paginate | --no-pager] [--no-replace-objects] [--bare]
[--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]
<command> [<args>]
2. 配置用户基本信息
每一条提交都会产生一条记录,这条记录标记了提交人的姓名与邮箱,以便他人查看与联系。
git config --global user.name "JacksonZhou"
git config --global user.email "1359926897@qq.com"
// 查看全局配置
git config --list
3. 配置 ssh
配置了 SSH 到指定服务器上,即说明让服务器信任你的笔记本,每次从 gitlab 或 github 拉代码和上传代码时不用输入用户名和密码
生成 ssh key
ssh-keygen -t rsa -C "1359926897@qq.com"
检查是否生成成功
cat ~/.ssh/id_rsa.pub
// ssh key 生成成功的话,就会看到如下输出
// ssh-rsa ......
复制 ssh-rsa 后面的内容,粘贴到你服务器网站的 SSH Key 配置项里面即完成配置,接下来就可以拉取代码了。
Git 基本操作
先看下 Git 的基本工作流 下面是一些实际开发过程常见的操作,更详细的内容建议查看 Git 中文手册
工作区 <—> 远程仓库
克隆远程仓库到本地
- git clone
git clone origin <remote_repo>
git clone -b <branch> <remote_repo> // 从指定分支拉取代码
连接远程仓库
- git remote
git remote add origin <remote_repo> // 链接远程仓库
git remote set-url origin <remote_repo> // 修改远程仓库
git remote rm origin // 删除远程仓库
git remote -v // 查看远程仓库列表
git remote show origin // 查看具体仓库细节
upstream
在 Github 上,我们可以 fork 任意开源项目到个人 ID 下,当我们把个人 ID 下的仓库 clone 到本地时,除了默认的 origin 仓库外,我们还需要配置一个 upstream 仓库,指向原始的开源项目地址,保证可以定期同步源仓库的更新。(用的比较少)
git remote add upstream <git_repository_url> // 建立 upstream 仓库
git remote remove upstream // 删除远程 upstream 仓库
实际开发过程中,如果没有先确定分支的追踪关系,当我们使用 git pull 或 git push 时就需要指定从远程的哪个分支拉取合并和推送到远程的哪个分支。
git branch -u <> <> // 指定本地分支和远程分支的追踪关系
git push -u <> <> // 确定追踪关系并提交代码
与远程仓库同步
- git pull
git pull origin <branch> // git fetch + git merge,从指定分支拉取代码并更新
git pull --rebase // git fetch + git rebase,不会生成 merge 记录,建议是用于个人分支
工作区 <—> 暂存区
提交
- git add
git add .
git add -i // 筛选想要提交的修改并提交
撤销
- git restore
暂存区 <—> 本地仓库
提交
- git commit
git commit -m "" // 提交代码到本地仓库
重新提交
如果发现已经提交了改动,但是还有修改也是需要合到那一部分改动中的,可以这样操作
git add .
git commit --amend -m ""
// amend 也可以单纯用来修改 commit 信息
撤销
- git reset - 适用于本地记录,即还没提交到远程仓库的记录
git reset HEAD^1 --hard // 重置为上一个 commit,并清空工作区域的代码改动
git reset HEAD^1 --soft // 重置为上一个 commit,不过会保留工作区域的代码改动
- git revert - 适用于已经提交到远程仓库的记录的撤销
commit message 规范
# 主 type
feat: 增加新功能
fix: 修复bug
# 其他 type
docs: 只改动了文档相关的内容
style: 不影响代码含义的改动,例如去掉空格、改变缩进、增删分号
build: 构造工具的或者外部依赖的改动,例如webpack,npm
refactor: 代码重构时使用
revert: 执行git revert打印的message
test: 添加测试或者修改现有测试
perf: 提高性能的改动
ci: 与CI(持续集成服务)有关的改动
chore: 不修改src或者test的其余修改,例如构建过程或辅助工具的变动
本地仓库 <—> 远程仓库
同步
- git fetch
- 从远程仓库下载本地仓库中缺失的提交记录
- 更新远程分支指针
提交
- git push
在多人协作的分支上尽量不用 git push -f、git rebase、reset 的操作
撤销
HEAD
HEAD 总是指向当前分支上最近一次提交记录。
git checkout <commit_hash> // 让 HEAD 指向指定的 commit
HEAD^ // 向前移动一个提交记录
HEAD^2 // TODO 移动到前面一排记录的第二个提交记录
HEAD~3 // 向前提交三个记录
通过 cat .git/head 可以查看 HEAD 指向
分支
- git branch - 创建本地分支
git branch '' // 创建分支
git switch '' // 切换分支
git checkout -b '' // 创建分支并切换到该分支
git branch -f <branch> <commit_hash/branch> // 将指定 branch 的 HEAD 指向某个提交记录或者某个分支的 HEAD
stash
git stash 可以将当前工作状态(WIP,work in progress)临时存放在 stash 列表中,待 pull / merge 操作完成后,再从 stash 中重新应用这些修改。
git stash list
git stash save 'message' // 存储一个自定义 message 的 WIP 到 stash 栈中
git stash -u save '' // -u 参数表明新增的文件也一起 stash
git stash pop // 恢复上一次的 WIP 状态,并从 stash 栈中移除
git stash pop stash@{num} // 恢复指定编号的 WIP,并从 stash 栈中移除
git stash apply stash@{num} // 恢复指定编号的 WIP,但不从 stash 栈中移除
如果 git stash 的文件刚好被其他提交修改过了,那么在 pop 时会自动将修改过的文件标记为 conflict 状态
合并代码
merge
该命令主要按以下两种策略合并代码:
Fast-forword(—ff)
no-fast-forword(—no-ff)
rebase
Rebase 实际上就是取出一系列的提交记录,将他们复制到其他地方。相比 merge,rebase 能提供更加线性的提交历史。这个操作比较危险,会改变提交历史,因此建议不要对已经处于远端的多人共用分支做 rebase 操作。
reword:修改提交信息;
edit:修改此提交;
squash:将提交融合到前一个提交中;
fixup:将提交融合到前一个提交中,不保留该提交的日志消息;
exec:在每个提交上运行我们想要 rebase 的命令;
drop:移除该提交。
复制记录
- cherry-pick - 可以复制指定的 commit
查看日志
- git config
// 1. git 配置 alias
git config --global alias.ls 'log --name-status --oneline --graph'
git ls
git config --global alias.lg "log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative"
git lg
// 2. 用 zsh 配置 alias
git show <commit_id> // 查看具体某次commit记录
git log -p -n // n是代表最近几次的提交,可以查看最近几次commit记录
开发实践
合并多个 commit
- git rebase -i HEAD~3 // 编辑最近三个记录
p HEAD1
s HEAD2
s HEAD3
如何修改之前的某个提交(已 push)?
- git rebase 先调整待修改的提交到最新
- 修改后提交
- git rebase 再调整回来
如何修改之前的某个 commit?
git commit --amend
— 修改 commit message 或追加文件改动建议用这个git reset HEAD^1 --soft
如何复制其他分支的文件夹到当前分支?
git checkout <branch> -- [file_name]